package com.athui.utils.common;

import com.athui.enums.DataRegularEnums;
import com.google.common.collect.*;
import org.apache.flink.api.java.tuple.Tuple3;
import org.apache.flink.api.java.tuple.Tuple5;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.regex.Matcher;

/**
 * @description: TODO
 * @autor: zhangzhonghui
 * @create: 2024-08-01 12:49
 * @Version: 1.0
 */
public class RegexMatchUtils {


    /**
     * @description: TODO 列名解析
     *  该函数的功能是分析给定的列名字符串，并提取出列名、精度和标度信息。它首先使用正则表达式匹配输入字符串（去除空格），
     *  然后根据匹配结果提取列名和参数。如果参数存在，将它们分割并转换为整数类型的精度和标度。最后，将列名、精度和标度封装到一个不可变的三元组（Tuple3）中并返回。
     * @autor: zhangzhonghui
     * @return: org.apache.flink.api.java.tuple.Tuple3<java.lang.String,java.lang.Integer,java.lang.Integer>
     * @create: 2024/8/1 13:06
     * @Version: 1.0
    **/
    public static Tuple3<String, Integer, Integer> columnNameAnalysis(String input) {
        Matcher matcher = DataRegularEnums.TEXT_COLUMN_NAME_PATTERN.getValue().matcher(input.replace(" ",""));

        String columnName = input;
        int precision = 0; // 精度
        int scale = 0; // 标度
        if (matcher.matches()) {
            columnName = matcher.group(1);
            String parameters = matcher.group(2);
            // Split parameters and convert to integers if needed
            String[] paramArray = parameters.split(",");
            if (paramArray.length > 1){
                precision = Integer.parseInt(paramArray[0].trim());
                scale = Integer.parseInt(paramArray[1].trim());
            }else{
                precision = Integer.parseInt(paramArray[0].trim());
            }
        }
        return Tuple3.of(columnName, precision, scale);
    }


    /**
     * @description: TODO 数据范围
     * @author: 阿辉大人
     * @param: value
     * @param: expression
     * @return: boolean
     * @create: 2024/8/22 16:16
     * @version: 1.0
    **/
    public static boolean inDataRange(BigDecimal value,String expression){
        return Arrays.stream(expression.split("\\|")).anyMatch(expr -> {
            Tuple5<Character, Character, String, String, Integer> t = rangeExpressionAnalysis(expr);
            return inDataRange(t.f0, t.f1,
                    t.f2.length() == 0 ? null : new BigDecimal(t.f2),
                    t.f3.length() == 0 ? null : new BigDecimal(t.f3),
                    t.f4,value,expression);
        });
    }

    /**
     * @description: TODO 文本范围匹配
     * @author: 阿辉大人
     * @param: value
     * @param: expression
     * @return: boolean
     * @create: 2024/8/23 23:09
     * @version: 1.0
    **/
    public static boolean inDataRange(String value,String expression){
        if (expression ==null){
            return false;
        }

       return Arrays.stream(expression.split("\\|")).anyMatch(expr -> {
           System.out.println(expr);
            Tuple5<Character, Character, String, String, Integer> t = rangeExpressionAnalysis(expr);
            return inDataRange(t.f0, t.f1,
                    t.f2.length() == 0 ? null : t.f2.hashCode(),
                    t.f3.length() == 0 ? null : t.f3.hashCode(),
                    t.f4, value.hashCode(), expr);
        });

    }


    /**
     * @description: TODO 范围表达式解析
     * @author: 阿辉大人
     * @param: expression
     * @create: 2024/8/23 22:57
     * @version: 1.0
     **/
    private static Tuple5<Character, Character, String, String, Integer> rangeExpressionAnalysis(String expression){
        char[] chars = expression.toCharArray();
        char leftChar = chars[0];
        char rightChar = chars[chars.length-1];

        int commaIndex =expression.indexOf(',');

        String leftValue;
        String rightValue = "";
        if (commaIndex==-1){
            // 只有一个元素，直接比较是否等于即可
            leftValue = expression.substring(1,chars.length-1);
        }else{
            leftValue = expression.substring(1,commaIndex);
            rightValue = expression.substring(commaIndex+1,chars.length-1);
        }

        return Tuple5.of(leftChar, rightChar, leftValue, rightValue, commaIndex);
    }

    /**
     * @description: TODO 数据范围比较
     *      *   (1, 10)：代表 1 < x < 10；
     *      *   (1, 10]：代表 1 < x <= 10；
     *      *   [1, 10]：代表 1 <= x <= 10；
     *      *   [1, 10)：代表 1 <= x < 10；
     *      *   (, 10) 或 [, 10)：代表 x < 10
     *      *   (, 10] 或 [, 10]：代表 x <= 10；
     * @author: 阿辉大人
     * @param: leftChar - left character
     * @param: rightChar - right character
     * @param: leftValue - left value
     * @param: rightValue - right value
     * @param: commaIndex - comma index
     * @param: value - value
     * @param: expression 表达式
     * @return: boolean
     * @create: 2024/8/23 23:00
     * @version: 1.0
    **/
    private static <T extends Comparable> boolean inDataRange(
            char leftChar,char rightChar,
            T leftValue,T rightValue,
            int commaIndex, T value,String expression){

        if (expression ==null){
            return false;
        }
        if(commaIndex == -1){
            return leftValue.compareTo(value) == 0;
        }


        if(leftChar =='(' && rightChar == ')'){
            if(leftValue !=null && rightValue !=null){
                // (a..b) {x | a < x < b}
                return Range.open(leftValue, rightValue).contains(value);
            }else if(leftValue !=null){
                // (a..+∞) {x | x > a}
                return Range.greaterThan(leftValue).contains(value);
            }else if (rightValue !=null){
                // (-∞..b) {x | x < b}
                return Range.lessThan(rightValue).contains(value);
            }else {
                // (-∞..+∞) {x | x is any value}
                return Range.all().contains(value);
            }

        }else if(leftChar == '[' && rightChar == ']'){
            if(leftValue !=null && rightValue !=null){
                // [a..b] {
                // | a <= x <= b}
                return Range.closed(leftValue,rightValue).contains(value);
            }
        }else if(leftChar == '[' && rightChar == ')'){
            if(leftValue !=null && rightValue !=null){
                // [a..b) {x | a <= x < b}
                return Range.closedOpen(leftValue, rightValue).contains(value);
            }else if(leftValue !=null){
                // [a..+∞) {x | x >= a}
                return Range.atLeast(leftValue).contains(value);
            }
        }else if(leftChar == '(' && rightChar == ']'){
            if(leftValue !=null && rightValue !=null){
                // (a..b] {x | a < x <= b}
                return Range.openClosed(leftValue, rightValue).contains(value);
            }else if(rightValue !=null){
                // (-∞..b] {x | x <= b}
                return Range.atMost(rightValue).contains(value);
            }
        }
        System.out.printf("%s 是一个无效的表达式!\n", expression);
        return false;
    }

    public static void main(String[] args) {
        System.out.println(inDataRange("女", "[女]")); // Expected output: false
    }
}

